package internal

import (
	"errors"
	"gorm.io/gorm"
	"k9-panel/app/model"
	"k9-panel/app/query"
)

type EnvironmentService struct {
}

func (receiver *EnvironmentService) Update(env *model.Environment) (id uint, err error) {
	if env == nil || env.ID == 0 {
		return 0, errors.New("env 不存在")
	}
	first, err := query.Environment.Where(query.Environment.ID.Eq(env.ID)).First()
	if err != nil {
		return 0, err
	}
	config, err := query.HistoryConfig.Where(query.HistoryConfig.EnvironmentId.Eq(int(first.ID))).First()
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return 0, err
	}
	if config != nil {
		return 0, errors.New("存在已发布配置，不允许修改！")
	}
	updates, err := query.Environment.Where(query.Environment.ID.Eq(env.ID)).Updates(env)
	if err != nil {
		return 0, err
	}
	return uint(updates.RowsAffected), nil
}

func (receiver *EnvironmentService) QueryByNames(names []string) ([]*model.Environment, error) {
	if len(names) == 0 {
		return nil, nil
	}
	return query.Environment.Where(query.Environment.Name.In(names...)).Find()
}

func (receiver *EnvironmentService) GetByModel(env *model.Environment) (*model.Environment, error) {
	if env == nil {
		return nil, errors.New("model is nil")
	}
	if env.ID > 0 {
		return receiver.Get(env.ID)
	}
	return query.Environment.Where(query.Environment.Name.Eq(env.Name)).First()
}

func (receiver *EnvironmentService) Create(model *model.Environment) (uint, error) {
	err := query.Environment.Create(model)
	if err != nil {
		return 0, err
	}
	return model.ID, err
}
func (receiver *EnvironmentService) Delete(model *model.Environment) (uint, error) {
	if model == nil {
		return 0, errors.New("model is nil")
	}
	if model.ID < 0 && model.Name != "" {
		qM, err := query.Environment.Where(query.Environment.Name.Eq(model.Name)).First()
		if err != nil {
			return 0, err
		}
		model = qM
	}
	findDerived, _ := query.DerivedConfig.Where(query.DerivedConfig.EnvironmentId.Eq(int(model.ID))).First()
	if findDerived != nil {
		return 0, errors.New("存在配置文件不能删除！")
	}
	res, err := query.Environment.Where(query.Environment.ID.Eq(model.ID)).Delete()
	if err != nil {
		return 0, err
	}
	return uint(res.RowsAffected), nil
}

func (receiver *EnvironmentService) List() ([]*model.Environment, error) {
	res, err := query.Environment.Find()
	if err != nil {
		return nil, err
	}
	return res, nil
}
func (receiver *EnvironmentService) Get(id uint) (*model.Environment, error) {

	res, err := query.Environment.Preload(query.Environment.Projects).Where(query.Environment.ID.Eq(id)).First()
	if err != nil {
		return res, err
	}
	return res, nil
}
